`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2023/11/30 13:15:49
// Design Name: 
// Module Name: sellers
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 状态机/售货机
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module sellers (
    input clk,
    input rstn,  // 复位
    input [1:0] coin,  // 投币金额 0：0元(未投/复位) 1: 0.5元 2：1元 3：错误
    output state,  // 输出当前状态 0:投币中 1:售出
    output [2:0] total  // 输出当前金额 0.5 * total元
);

  parameter IDLE = 2'd0;
  parameter GET05 = 2'd1;
  parameter GET10 = 2'd2;
  parameter GET15 = 2'd3;

  reg [2:0] state_next;  // 下一个状态
  reg [2:0] state_current;  // 当前状态
  reg [1:0] total_temp;  // 当前找零金额
  reg state_temp;  // 当前状态
  initial begin
    state_temp = 0;
    total_temp = 0;
    state_current = 0;
  end
  // 变更当前状态
  always @(posedge clk or negedge rstn) begin
    if (!rstn) begin
      state_current <= 0;
    end else begin
      state_current <= state_next;
    end
  end

  // 计算下一个状态
  always @(*) begin
    case (state_current)
      IDLE: begin
        case (coin)
          GET05:   state_next = GET05;
          GET10:   state_next = GET10;
          default: state_next = IDLE;
        endcase
      end
      GET05: begin
        case (coin)
          GET05:   state_next = GET10;
          GET10:   state_next = GET15;
          default: state_next = GET05;
        endcase
      end
      GET10: begin
        case (coin)
          GET05:   state_next = GET15;
          GET10:   state_next = IDLE;
          default: state_next = GET10;
        endcase
      end
      GET15: begin
        case (coin)
          GET05:   state_next = IDLE;
          GET10:   state_next = IDLE;
          default: state_next = GET15;
        endcase
      end
      default: state_next = IDLE;
    endcase
  end

  // 确认输出状态
  always @(posedge clk or negedge rstn) begin
    if (!rstn) begin
      state_temp <= 0;
      total_temp <= 0;
    end else if ((state_current == GET10 && coin == 2'd2) || (state_current == GET15 && coin == 2'd1)) begin
      state_temp <= 1;
      total_temp <= 0;
    end else if (state_current == GET15 && coin == 2'd2) begin
      state_temp <= 1;
      total_temp <= 1;
    end else begin
      state_temp <= 0;
      total_temp <= 0;
    end
  end

  assign state = state_temp;  // 输出数据
  assign total = total_temp;  // 输出数据

endmodule
